
package taller2.controller.modes.supervisor;

import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Stack;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

import taller2.controller.modes.Mode;
import taller2.interfaces.Connection;
import taller2.interfaces.Graph;
import taller2.interfaces.Node;
import taller2.utils.Constants;
import taller2.utils.Point;
import taller2.view.draws.DrawingArea;
import taller2.view.draws.GraphDrawer;

public class DfsSupervisorMode implements Mode {
	private Graph graph;
	private Node actual;

	Stack<Node> stack; 
	
	private boolean finished;
	
	// constructor
	public DfsSupervisorMode(Graph graph){
		this.graph = graph;
		this.actual = null;
		
		Node start = getStartingNode();

		this.stack = new Stack<Node>();
		this.stack.add(start);

		this.finished = false;
		
	}
	
	private void addConnectedNodes(ArrayList<Node> array,Node node) {
		for(Connection connection : node.getConnections()){
			Node other = connection.getOtherNode();
			if(!other.isSelected() && !array.contains(other))
				array.add(other);
		}
	}

	private Node getStartingNode(){
		ArrayList<Node> nodes = graph.getNodes();
		for (Node node : nodes){
			if (node.isSelected())
				return node;
		}
		return nodes.get(0);
	}
	
	public void whenPressed(MouseEvent arg0, DrawingArea area) {
		GraphDrawer drawer = area.getDrawer();
		Point pos = new Point(arg0.getX(),arg0.getY());
		if(!finished)
			supervise(drawer,area,pos);
	}
	
	private void supervise(GraphDrawer drawer, DrawingArea area,Point pos){
		actual = drawer.getCloseByNode(pos);
		if(actual != null)
			processSolution();
		
		if(allNodesSelected()){
			JFrame frame = new JFrame();
			JOptionPane.showMessageDialog(frame,Constants.okMsg);

			finished = true;
		}
				
		selectConnections();
		area.repaint();
	}

	private void processSolution(){
		ArrayList<Node> posibleSolutions = new ArrayList<Node>();

		
		if(stack.isEmpty()){	 // caso nodos sueltos
			actual.select(); 
			stack.add(actual);
		}else{
			do{												// obtengo sol posibles
				Node node = stack.peek();
				addConnectedNodes(posibleSolutions,node);
				
				if(posibleSolutions.isEmpty())
					stack.pop();
				
				if(stack.isEmpty() && posibleSolutions.isEmpty()){
					actual.select(); 
					stack.add(actual);
					return;
				}
				
			}while(posibleSolutions.isEmpty());
	
			for(Node node : posibleSolutions){						// me fijo si el q elijio es correcto
				if((actual != null) && (actual.equals(node))){
					stack.add(actual);
					actual.select(); 
					return;
				}				
			}
		
			JFrame frame = new JFrame();
			JOptionPane.showMessageDialog(frame,Constants.errorMsg);			
		}
	}
	
	private void selectConnections(){
		for(Connection conn : graph.getAllConnections().values()){
			Node node = conn.getOtherNode();
			Node node2 = conn.getThisNode();
			if(node.isSelected() && node2.isSelected())
				conn.select();
		}
	}
	
	private boolean allNodesSelected() {
		for(Node node : graph.getNodes()){
			if(!node.isSelected())
				return false;
		}
		return true;
	}
	
	public void whenReleased(MouseEvent arg0, DrawingArea area) {}

	public void whenDragged(MouseEvent arg0, DrawingArea area) {}

}
